package com.wangmin.intercept.websetting;

import android.app.Activity;
import android.app.Instrumentation;
import android.content.ClipData;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.media.MediaPlayer;
import android.net.Uri;
import android.util.Log;
import android.view.KeyEvent;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.ConsoleMessage;
import android.webkit.GeolocationPermissions;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.widget.FrameLayout;
import android.widget.TextView;

import com.wangmin.intercept.R;
import com.wangmin.intercept.init.SdkInit;
import com.wangmin.intercept.listener.IuploadFile;
import com.wangmin.intercept.listener.IwebChromeClient;
import com.wangmin.intercept.listener.ToggledFullscreenCallback;
import com.wangmin.intercept.listener.WebchromClientCallback;
import com.wangmin.intercept.utils.LogUtils;
import com.wangmin.intercept.view.AudioAutoShowTitleFramLayout;

import java.util.Timer;
import java.util.TimerTask;



/**
 * Created by wm on 2016/11/11.
 */
public class CustomWebChromeClient extends WebChromeClient implements MediaPlayer.OnPreparedListener, MediaPlayer.OnCompletionListener, MediaPlayer.OnErrorListener,IuploadFile,IwebChromeClient {
    private View activityNonVideoView;
    private ViewGroup activityVideoView;
    private View loadingView;
    private CustomWebview webView;
    private Bitmap mDefaultVideoPoster;
    private Context context;
    private View titleView;
    private View back;
    private Timer timer;
    private View rlContent;
    private TextView tvTitle;
    private ValueCallback<Uri[]> mUploadCallbackAboveFive;
    private ValueCallback<Uri> mUploadMsg;
    public static final int FILECHOOSER_RESULTCODE = 10000;
    @SuppressWarnings("unused")
    public CustomWebChromeClient()
    {

    }

    @SuppressWarnings("unused")
    public CustomWebChromeClient(View activityNonVideoView, ViewGroup activityVideoView)
    {
        this.activityNonVideoView = activityNonVideoView;
        this.activityVideoView = activityVideoView;
        this.loadingView = null;
        this.webView = null;
        this.isVideoFullscreen = false;
    }

    /**
     * Builds a video enabled WebChromeClient.
     * @param activityNonVideoView A View in the activity's layout that contains every other view that should be hidden when the video goes full-screen.
     * @param activityVideoView A ViewGroup in the activity's layout that will display the video. Typically you would like this to fill the whole layout.
     * @param loadingView A View to be shown while the video is loading (typically only used in API level <11). Must be already inflated and not attached to a parent view.
     */
    @SuppressWarnings("unused")
    public CustomWebChromeClient(View activityNonVideoView, ViewGroup activityVideoView, View loadingView)
    {
        this.activityNonVideoView = activityNonVideoView;
        this.activityVideoView = activityVideoView;
        this.loadingView = loadingView;
        this.webView = null;
        this.isVideoFullscreen = false;

    }

    /**
     * Builds a video enabled WebChromeClient.
     * @param activityNonVideoView A View in the activity's layout that contains every other view that should be hidden when the video goes full-screen.
     * @param activityVideoView A ViewGroup in the activity's layout that will display the video. Typically you would like this to fill the whole layout.
     * @param loadingView A View to be shown while the video is loading (typically only used in API level <11). Must be already inflated and not attached to a parent view.
     * @param webView The owner VideoEnabledWebView. Passing it will enable the VideoEnabledWebChromeClient to detect the HTML5 video ended event and exit full-screen.
     * Note: The web page must only contain one video tag in order for the HTML5 video ended event to work. This could be improved if needed (see Javascript code).
     */
    @SuppressWarnings("unused")
    public CustomWebChromeClient(View activityNonVideoView, ViewGroup activityVideoView, View loadingView, CustomWebview webView, Context context)
    {
        this.activityNonVideoView = activityNonVideoView;
        this.rlContent = activityVideoView;
        this.activityVideoView = (ViewGroup) rlContent.findViewById(R.id.videoLayout);
        this.loadingView = loadingView;
        this.webView = webView;
        this.isVideoFullscreen = false;
        this.context = context;
        titleView = activityVideoView.findViewById(R.id.title);
        back = activityVideoView.findViewById(R.id.iv_back);
        back.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(isVideoFullscreen) {
                    new Thread(){
                        @Override
                        public void run() {
                            try {
                                Instrumentation inst = new Instrumentation();
                                inst.sendKeyDownUpSync(KeyEvent.KEYCODE_BACK);
                            }catch (Exception e){
                                SdkInit.getUiHandle().post(new Runnable() {
                                    @Override
                                    public void run() {
                                        onHideCustomView();
                                    }
                                });
                            }catch (Error error){
                                SdkInit.getUiHandle().post(new Runnable() {
                                    @Override
                                    public void run() {
                                        onHideCustomView();
                                    }
                                });
                            }
                        }
                    }.start();
                }
            }
        });
        if(rlContent instanceof AudioAutoShowTitleFramLayout){
            AudioAutoShowTitleFramLayout audioAutoShowTitleFramLayout = (AudioAutoShowTitleFramLayout) rlContent;
            audioAutoShowTitleFramLayout.setAudioAutoShowTitleFramLayoutOnClickListener(new AudioAutoShowTitleFramLayout.AudioAutoShowTitleFramLayoutOnClickListener() {
                @Override
                public void onclick() {
                    showAndBeginToInvisiable();
                }
            });
        }
        tvTitle = (TextView) activityVideoView.findViewById(R.id.tv_title);
        tvTitle.setText(webView.getTitle());
        showAndBeginToInvisiable();
    }
    public void showAndBeginToInvisiable(){
        if(titleView.getVisibility() == View.VISIBLE){
            return;
        }
        titleView.setVisibility(View.VISIBLE);
        if(timer!=null) {
            timer.cancel();
            timer = null;
        }
        if(timer == null){
            timer = new Timer();
        }
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                SdkInit.getUiHandle().post(new Runnable() {
                    @Override
                    public void run() {
                        titleView.setVisibility(View.GONE);
                    }
                });
            }
        },3000);
    }

    @Override
    public void onReceivedTitle(WebView view, String title) {
        super.onReceivedTitle(view, title);
        LogUtils.getNewInstance("CustomWebChromeClient").dob(title);
        tvTitle.setText(title);
    }

    private boolean isVideoFullscreen; // Indicates if the video is being displayed using a custom view (typically full-screen)
    private FrameLayout videoViewContainer;
    private CustomViewCallback videoViewCallback;

    private ToggledFullscreenCallback toggledFullscreenCallback;


    public void setOnToggledFullscreen(ToggledFullscreenCallback callback)
    {
        this.toggledFullscreenCallback = callback;
    }

    @Override
    public void onShowCustomView(View view, CustomViewCallback callback) {
        LogUtils.getNewInstance("CustomWebChromeClient").dob(""+view);

        if (view instanceof FrameLayout)
        {
            // A video wants to be shown
            FrameLayout frameLayout = (FrameLayout) view;
            View focusedChild = frameLayout.getFocusedChild();

            // Save video related variables
            this.isVideoFullscreen = true;
            this.videoViewContainer = frameLayout;
            this.videoViewCallback = callback;
            showAndBeginToInvisiable();
            // Hide the non-video view, add the video view, and show it
            activityNonVideoView.setVisibility(View.INVISIBLE);
            videoViewContainer.setBackgroundColor(Color.BLACK);
            activityVideoView.addView(videoViewContainer, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
            rlContent.setVisibility(View.VISIBLE);
            activityVideoView.setVisibility(View.VISIBLE);
            if (focusedChild instanceof android.widget.VideoView)
            {
                // android.widget.VideoView (typically API level <11)
                android.widget.VideoView videoView = (android.widget.VideoView) focusedChild;
                focusedChild.scrollTo(0,0);
                // Handle all the required events
                videoView.setOnPreparedListener(this);
                videoView.setOnCompletionListener(this);
                videoView.setOnErrorListener(this);
            }
            else
            {
                // Other classes, including:
                // - android.webkit.HTML5VideoFullScreen$VideoSurfaceView, which inherits from android.view.SurfaceView (typically API level 11-18)
                // - android.webkit.HTML5VideoFullScreen$VideoTextureView, which inherits from android.view.TextureView (typically API level 11-18)
                // - com.android.org.chromium.novel_content.browser.ContentVideoView$VideoSurfaceView, which inherits from android.view.SurfaceView (typically API level 19+)

                // Handle HTML5 video ended event only if the class is a SurfaceView
                // Test case: TextureView of Sony Xperia T API level 16 doesn't work fullscreen when loading the javascript below
                if (webView != null && webView.getSettings().getJavaScriptEnabled() && focusedChild instanceof SurfaceView)
                {
                    // Run javascript code that detects the video end and notifies the Javascript interface
                    String js = "javascript:";
                    js += "var _ytrp_html5_video_last;";
                    js += "var _ytrp_html5_video = document.getElementsByTagName('video')[0];";
                    js += "if (_ytrp_html5_video != undefined && _ytrp_html5_video != _ytrp_html5_video_last) {";
                    {
                        js += "_ytrp_html5_video.controls = false;";
                        js += "_ytrp_html5_video_last = _ytrp_html5_video;";
                        js += "function _ytrp_html5_video_ended() {";
                        {
                            js += "jsObj.notifyVideoEnd();"; // Must match Javascript interface name and method of VideoEnableWebView
                        }
                        js += "}";
                        js += "_ytrp_html5_video.addEventListener('ended', _ytrp_html5_video_ended);";
                    }
                    js += "}";
                    LogUtils.getNewInstance("CustomWebChromeClient").eob("白边到这了");
                    tvTitle.setText(webView.getTitle());
                    webView.loadUrl(js);
                }
            }

            // Notify full-screen change
            if (toggledFullscreenCallback != null)
            {
                toggledFullscreenCallback.toggledFullscreen(true);
            }
        }
    }

    @Override
    public void onShowCustomView(View view, int requestedOrientation, CustomViewCallback callback) {
        super.onShowCustomView(view,requestedOrientation,callback);
        onShowCustomView(view,callback);
    }

    @Override
    public void onHideCustomView() {
        // This method should be manually called on video end in all cases because it's not always called automatically.
        // This method must be manually called on icon_back key press (from this class' onBackPressed() method).
        Log.e("CustomWebChromeClient", "onHideCustomView()");
        if (isVideoFullscreen)
        {
            // Hide the video view, remove it, and show the non-video view
            rlContent.setVisibility(View.INVISIBLE);
            activityVideoView.setVisibility(View.INVISIBLE);
            activityVideoView.removeView(videoViewContainer);
            activityNonVideoView.setVisibility(View.VISIBLE);
            if (videoViewCallback != null && !videoViewCallback.getClass().getName().contains(".chromium."))
            {
                videoViewCallback.onCustomViewHidden();
            }
            // Call icon_back (only in API level <19, because in API level 19+ with chromium webview it crashes)
            // Reset video related variables
            isVideoFullscreen = false;
            videoViewContainer = null;
            videoViewCallback = null;

            // Notify full-screen change
            if (toggledFullscreenCallback != null)
            {
                toggledFullscreenCallback.toggledFullscreen(false);
            }
        }
    }
    @Override
    public View getVideoLoadingProgressView() // Video will start loading
    {
        Log.e("CustomWebChromeClient", "getVideoLoadingProgressView()");
        if (loadingView != null)
        {
            loadingView.setVisibility(View.VISIBLE);
            return loadingView;
        }
        else
        {
            return super.getVideoLoadingProgressView();
        }
    }
    @Override
    public void onPrepared(MediaPlayer mp) // Video will start playing, only called in the case of android.widget.VideoView (typically API level <11)
    {
        Log.e("CustomWebChromeClient", "onPrepared()");
        if (loadingView != null)
        {
            loadingView.setVisibility(View.GONE);
        }
    }

    @Override
    public void onCompletion(MediaPlayer mp) // Video finished playing, only called in the case of android.widget.VideoView (typically API level <11)
    {
        Log.e("CustomWebChromeClient", "onCompletion()");
        onHideCustomView();
    }

    @Override
    public boolean onError(MediaPlayer mp, int what, int extra) // Error while playing video, only called in the case of android.widget.VideoView (typically API level <11)
    {
        Log.e("CustomWebChromeClient","error"+what+"  "+extra);
        return false; // By returning false, onCompletion() will be called
    }

    /**
     * Notifies the class that the icon_back key has been pressed by the user.
     * This must be called from the Activity's onBackPressed(), and if it returns false, the activity itself should handle it. Otherwise don't do anything.
     * @return Returns true if the event was handled, and false if was not (video view is not visible)
     */
    @SuppressWarnings("unused")
    public boolean onBackPressed()
    {
        Log.e("CustomWebChromeClient", "onBackPressed()");
        if (isVideoFullscreen)
        {
            onHideCustomView();
            return true;
        }
        else
        {
            return false;
        }
    }

    public boolean isVideoFullscreen() {
        return isVideoFullscreen;
    }

    private WebchromClientCallback clientCallback;
    public void setWebchromClientCallback(WebchromClientCallback clientCallback){
        this.clientCallback = clientCallback;
    }
    @Override
    public void onProgressChanged(WebView view, int newProgress) {
        if(clientCallback!=null){
            clientCallback.onProgressChanged(view,newProgress);
        }
        super.onProgressChanged(view, newProgress);
    }

    @Override
    public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) {
        if(clientCallback!=null){
            clientCallback.onGeolocationPermissionsShowPrompt(origin,callback);
        }
        super.onGeolocationPermissionsShowPrompt(origin, callback);
    }

    //        @Override
//    public Bitmap getDefaultVideoPoster() {
//        Log.e("CustomWebChromeClient", "getDefaultVideoPoster()");
//        if (mDefaultVideoPoster == null) {
//            mDefaultVideoPoster = BitmapFactory.decodeResource(SdkInit.getContext().getResources(), R.drawable.default_video_poster);
//        }
//        return mDefaultVideoPoster;
//    }

    @Override
    public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
        Log.d("CustomWebChromeClient",""+consoleMessage.message()+"  consoleMessage.sourceId():"+consoleMessage.sourceId()+"  consoleMessage.lineNumber():"+consoleMessage.lineNumber()+"  consoleMessage.messageLevel():"+consoleMessage.messageLevel());
        return super.onConsoleMessage(consoleMessage);
    }

    @Override
    public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
        mUploadCallbackAboveFive = filePathCallback;
        Intent i = new Intent(Intent.ACTION_GET_CONTENT);
        i.addCategory(Intent.CATEGORY_OPENABLE);
        i.setType("*/*");
        if(context instanceof Activity) {
            Activity activity = (Activity) context;
            activity.startActivityForResult(Intent.createChooser(i, "File Chooser"), FILECHOOSER_RESULTCODE);
        }
        return true;
    }

    // For Android < 3.0
    public void openFileChooser(ValueCallback<Uri> uploadMsg) {
        openFileChooser(uploadMsg, "", "");
    }

    // For Android 3.0+
    public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
        openFileChooser(uploadMsg, acceptType, "");
    }

    //For Android 4.1
    public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
        mUploadMsg = uploadMsg;
        Intent i = new Intent(Intent.ACTION_GET_CONTENT);
        i.addCategory(Intent.CATEGORY_OPENABLE);
        i.setType("*/*");
        if(context instanceof Activity) {
            Activity activity = (Activity) context;
            activity.startActivityForResult(Intent.createChooser(i, "File Chooser"), FILECHOOSER_RESULTCODE);
        }
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (null == mUploadCallbackAboveFive) {
            return;
        }
        Uri[] results = null;
        if (resultCode == Activity.RESULT_OK) {
            if (data != null) {
                String dataString = data.getDataString();
                ClipData clipData = null;
                try {
                    clipData = data.getClipData();
                }catch (Exception e){
                    clipData = null;
                }
                if (clipData != null) {
                    int itemCount = clipData.getItemCount();
                    results = new Uri[itemCount];
                    for (int i = 0; i < itemCount; i++) {
                        ClipData.Item item = clipData.getItemAt(i);
                        results[i] = item.getUri();
                    }
                }
                if (dataString != null) {
                    results = new Uri[]{Uri.parse(dataString)};
                }
            }
        }
        if(mUploadMsg!=null&&results!=null&&results.length>0){
            mUploadMsg.onReceiveValue(results[0]);
        }
        if(mUploadCallbackAboveFive!=null) {
            mUploadCallbackAboveFive.onReceiveValue(results);
        }
        mUploadCallbackAboveFive = null;
    }
}
